<template>
  <el-drawer
    title="研判分析"
    v-model="show"
    size="85%"
    @open="handleOpen"
    @close="handleClose"
    class="el-drawer--full"
  >
    <div class="page">
      <div class="page-left">
        <Section style="flex: 1" full title="告警信息">
          <div class="info">
            <div class="info-item">
              <div class="info-item--label">主机名称：</div>
              <div class="info-item--value">{{ data.host_name }}</div>
            </div>
            <div class="info-item">
              <div class="info-item--label">告警类型：</div>
              <div class="info-item--value">{{ data.alert_type }}</div>
            </div>
            <div class="info-item">
              <div class="info-item--label">告警等级：</div>
              <div class="info-item--value">
                <div class="level" :class="`level--${data.level}`">
                  {{
                    {
                      high: '高危',
                      middle: '中危',
                      low: '低危',
                    }[data.level] || data.level
                  }}
                </div>
              </div>
            </div>
          </div>

          <div class="title">研判步骤</div>
          <div class="step">
            <div
              class="step-item"
              v-for="(item, index) in infos"
              :class="{
                'step-item--active': active == index,
                'step-item--success': item.status === 2,
                'step-item--loading': item.status === 1,
              }"
              @click="handleStepClick(index)"
            >
              <div class="step-item-warp">
                <div class="step-item-number">
                  <template v-if="item.status === 1">
                    <el-icon class="is-loading"><Loading /></el-icon>
                  </template>
                  <template v-else>
                    {{ index + 1 }}
                  </template>
                </div>
                <div class="step-item-label">{{ item.label }}</div>
                <div class="step-item-status">
                  {{ { 0: '等待中', 1: '分析中', 2: '已完成' }[item.status] }}
                </div>
              </div>
            </div>
          </div>
        </Section>
      </div>

      <div class="page-right">
        <template v-if="infos[active]?.status == 1">
          <Section class="loading">
            <div class="header">
              <div class="icon">
                <el-icon>
                  <Search />
                </el-icon>
              </div>
              <div class="body">
                <div class="title">正在分析</div>
                <div class="desc">系统正在进行深度分析...</div>
              </div>
            </div>
          </Section>
        </template>

        <div class="content" v-if="infos[active]?.message">
          <!-- 告警研判 -->

          <Section title="拓扑图" class="topo" full>
            <!-- <YpTopo :data="infos[active].message.topology" /> -->
            <YpTopoNew :data="infos[active].message.topology" />
          </Section>

          <div class="sidebar">
            <template v-if="active == 2">
              <Section scrollbar title="分析" :allowFold="true" v-model:fold="moduleData.data.analysisFold">
                <template #icon v-if="moduleData.data.status >= STATUS_FX_WC">
                  <el-icon style="color: #67c23a"><SuccessFilled /></el-icon>
                </template>

                <app-markdown
                  :content="moduleData.message.assessment_analysis"
                  :typing="typing"
                  :allowFold="true"
                  @finish="handleFinish('analysis')"
                />
              </Section>

              <template v-if="moduleData.data.status >= STATUS_FX_WC">
                <Section
                  scrollbar
                  title="结果"
                  :allowFold="true"
                  v-model:fold="moduleData.data.guessFold"
                  :class="{ attack: moduleData.message.assessment_result == 'attack' }"
                >
                  <!-- <template #icon v-if="moduleData.data.status >= STATUS_FX_WC">
                  <el-icon style="color: #67c23a"><SuccessFilled /></el-icon>
                </template> -->

                  <template v-if="moduleData.message.assessment_result == 'attack'">
                    <!-- <el-tag  type="danger">
                  攻击行为
                </el-tag> -->
                    攻击行为
                  </template>

                  <el-tag v-else type="primary">正常行为</el-tag>
                </Section>

                <Section
                  title="攻击步骤"
                  v-if="moduleData.message?.attacksteps?.length && moduleData.data.status >= 3"
                  scrollbar
                  full
                >
                  <AttackStep :data="moduleData.message.attacksteps" :typing="typing" />
                </Section>
              </template>
            </template>
            <template v-else>
              <Section
                full
                scrollbar
                title="分析"
                :allowFold="true"
                v-model:fold="moduleData.data.analysisFold"
              >
                <template #icon v-if="moduleData.data.status >= STATUS_FX_WC">
                  <el-icon style="color: #67c23a"><SuccessFilled /></el-icon>
                </template>

                <app-markdown
                  :content="moduleData.message.analysis"
                  :typing="typing"
                  @finish="handleFinish('analysis')"
                />
              </Section>

              <!-- 分析完成后再显示推测 -->
              <Section
                v-if="moduleData.data.status >= STATUS_FX_WC"
                full
                scrollbar
                title="推测"
                :allowFold="true"
                v-model:fold="moduleData.data.guessFold"
              >
                <template #icon v-if="moduleData.data.status >= STATUS_TC_WC">
                  <el-icon style="color: #67c23a"><SuccessFilled /></el-icon>
                </template>

                <app-markdown
                  :content="moduleData.message.guess"
                  :typing="typing"
                  @finish="handleFinish('guess')"
                />
              </Section>
            </template>
          </div>
        </div>
      </div>
    </div>
  </el-drawer>
</template>

<script setup>
// import http, { post } from '@/utils/http'
import axios from 'axios'
import YpTopo from './YpTopo.vue'
import Section from './Section.vue'
import EchartGraph from './EchartGraph.vue'
import result from '../result.json'

import YpTopoNew from './YpTopoNew2.vue'
import AttackStep from './AttackStep.vue'

const typing = { setp: 20, interval: 20 }

const emits = defineEmits(['update:modelValue'])
const props = defineProps({
  modelValue: { type: Boolean, default: false },
  data: { type: Object },
  isTest: false,
})

const show = computed({
  get: () => props.modelValue,
  set: val => emits('update:modelValue', val),
})

// 当前
const moduleData = computed(() => {
  return infos.value[active.value]
})

const STATUS_FX_WC = 1 // 分析完成
const STATUS_TC_WC = 2 // 推测完成

const active = ref(0) // 当前
const resultIndex = ref(null) // 后台返回数据到几条了
const messages = ref([])
const texts = ref([])
const loading = ref(true)

const moduleKeys = ['jcfx', 'xwfx', 'ghyp']
const moduleDatas = ref({
  jcfx: {
    status: 0, // 0:等待中 1:分析中 2:推测完成

    analysisFold: true, // 分析折叠
    analysis: false, // 分析完成

    guessFold: true, // 推测完成折叠
    guess: false, // 推测完成
  },
  xwfx: {
    status: 0, // 0:等待中 1:分析中 2:推测完成

    analysisFold: true, // 分析折叠
    analysis: false, // 分析完成

    guessFold: true, // 推测完成折叠
    guess: false, // 推测完成
  },
  ghyp: {
    status: 0, // 0:等待中 1:分析中 2:推测完成

    analysisFold: true, // 分析折叠
    analysis: false, // 分析完成

    guessFold: true, // 推测完成折叠
    guess: false, // 推测完成
  },
})

const infos = computed(() => {
  const labels = [
    '进程分析',
    '行为分析',
    '告警研判',
    //  '告警溯源'
  ]
  const topoLabels = ['进程树', '进程树', '告警研判', '告警研判']
  const data = []

  labels.forEach((label, index) => {
    let message = messages.value[index]
    let text = texts.value[index]
    let status = 0
    let percentage = 0

    // 进行中
    if (messages.value.length == index) {
      status = 1
    }

    // 有字符串了
    if (text) percentage = 25

    // 有完整JSON了
    if (message) {
      status = 2
      percentage = 100
    }

    data.push({
      label,
      // messages: index,
      // result: index,
      message,
      text,
      status,
      percentage,
      analysis: false, // 分析完成
      guess: false, // 推测完成
      data: moduleDatas.value[moduleKeys[index]],
    })
  })

  return data
})

const check = () => {
  clearInterval(timer)

  if (resultIndex.value != null) {
    const data = moduleDatas.value[moduleKeys[active.value]]

    // 等待中
    if (data.status == 0) {
      data.analysisFold = false // 分析-展开
      console.log(`${active.value} 等待数据`)
    }
    // 分析完成
    else if (data.status == STATUS_FX_WC) {
      data.analysisFold = true // 分析-折叠
      data.guessFold = false // 推测-展开
      console.log(`${active.value} 分析完成，推测展开`)
    }

    // 可以进行下一步
    if (resultIndex.value > active.value) {
      // 当前推测完成
      if (data.status == STATUS_TC_WC) {
        console.log('推测完成+1')
        active.value = active.value + 1
      }
    }
  }

  timer = setInterval(check, 1000)
}

// 1、进程分析
// 2、进程行为分析
// 3、告警研判
// 4、告警溯源

let timer

const handleOpen = () => {
  check()

  // if (result) {
  //   messages.value = [result]
  //   texts.value = [JSON.stringify(result, null, 2)]
  //   loading.value = false
  //   return
  // }

  moduleDatas.value = {
    jcfx: {
      status: 0, // 0:等待中 1:分析中 2:推测完成

      analysisFold: true, // 分析折叠
      analysis: false, // 分析完成

      guessFold: true, // 推测完成折叠
      guess: false, // 推测完成
    },
    xwfx: {
      status: 0, // 0:等待中 1:分析中 2:推测完成

      analysisFold: true, // 分析折叠
      analysis: false, // 分析完成

      guessFold: true, // 推测完成折叠
      guess: false, // 推测完成
    },
    ghyp: {
      status: 0, // 0:等待中 1:分析中 2:推测完成

      analysisFold: true, // 分析折叠
      analysis: false, // 分析完成

      guessFold: true, // 推测完成折叠
      guess: false, // 推测完成
    },
  }

  active.value = 0
  messages.value = []
  texts.value = []
  loading.value = true

  let buffer = ''

  axios.post(
    // 'http://localhost:3033/events2',
    '/v1/hids/alert/assessment',
    {
      id: props.data.id,
      attack_code: props.data.attack_code,
      raw_data: JSON.parse(props.data.raw_data),
    },
    {
      onDownloadProgress: progressEvent => {
        loading.value = false
        let { responseText } = progressEvent.event.target

        // console.log('responseText', responseText)

        const data = responseText.split('\n\n')

        messages.value = []
        texts.value = []

        data.forEach(val => {
          const message = val.split('data:').pop()
          // console.log('message', message, typeof message)

          if (message == '') return

          try {
            const json = JSON.parse(message)

            json.topology = JSON.parse(json.topology)
            if (json.attacksteps) json.attacksteps = JSON.parse(json.attacksteps)

            messages.value.push(json)
          } catch (e) {
            console.error(e)
            // console.error('message', message)
          }
        })

        if (messages.value) resultIndex.value = messages.value.length - 1

        // if (active.value == 0) {
        //   const moduleKey = moduleKeys[active.value]

        //   console.log('moduleKey', moduleKey)

        //   // 展开分析
        //   moduleDatas.value[moduleKey].analysisFold = false
        // }

        // buffer += responseText

        // 检查是否收到完整消息（例如以换行符或特定标记结尾）
        // if (buffer.endsWith('\n\n')) {
        //   try {
        //     const completeData = buffer.trim()
        //     console.log('完整数据:', completeData)

        //     // 处理完整数据...
        //     // processCompleteData(completeData)

        //     // 清空缓冲区
        //     buffer = ''
        //   } catch (error) {
        //     console.error('Error processing data:', error)
        //   }
        // }
        // console.log(`第${count++}条数据`)
        // console.log('responseText', responseText)
        // // const ary = responseText.split('data:')

        // // console.log('ary', ary)

        // // results.push(ary)
      },
    },
  )
}

const handleClose = () => {
  clearInterval(timer)
}

const handleStepClick = index => {
  active.value = index
}

const handleFinish = type => {
  const key = moduleKeys[active.value]

  if (moduleDatas.value[key].status >= 2) return

  if (type == 'analysis') {
    moduleDatas.value[key].status = STATUS_FX_WC // 分析完成
    console.log('分析完成', moduleDatas.value[key].status)

    // 动画结束
    if (active.value == 2) {
      moduleDatas.value[key].analysisFold = true
      moduleDatas.value[key].guessFold = false

      if (messages.value[active.value].attacksteps) {
        setTimeout(() => {
          // moduleDatas.value[key].guessFold = true
          moduleDatas.value[key].status = 3
        }, 1500)
      }

      return clearInterval(timer)
    }
  } else if (type == 'guess') {
    moduleDatas.value[key].status = STATUS_TC_WC // 推测完成
    console.log('推测完成', moduleDatas.value[key].status)
  }

  // check()
}
</script>

<style lang="scss" scoped>
.header {
  display: flex;
  align-items: center;

  .icon {
    background-color: #e3e9f7;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 100%;
    color: #2350d8;
    font-size: 16px;
  }

  .body {
    margin-left: 12px;
    // animation: centerPulse 2s infinite ease-in-out;
  }

  .title {
    color: #000;
    font-weight: bold;
  }
  .desc {
    font-size: 12px;
    color: #999;
  }
}

.step {
  display: flex;
  flex-direction: column;
  position: relative;
  justify-content: space-between;
  margin: 0 20%;
  overflow: hidden;
  flex: 1;
  &::after {
    content: '';
    position: absolute;
    width: 1px;
    height: 100%;
    background-color: #e5e6eb;
    left: 50%;
  }
}

.step-item {
  position: relative;
  &::before {
    width: 9999px;
    background-color: #e5e6eb;
    height: 2px;
    z-index: 1;
    position: absolute;
    left: 0;
    top: 16px;
    content: '';
    z-index: 1;
  }
  &:last-child::before {
    display: none;
  }
}

.step-item-warp {
  display: flex;
  align-items: center;
  flex-direction: column;
  flex: 1;
  cursor: pointer;
  background-color: #fff;
  z-index: 2;
  position: relative;
}

.step-item-icon {
  width: 48px;
  height: 48px;
  background-color: #f3f4f6;
  border-radius: 100%;
  margin-bottom: 6px;

  display: flex;
  align-items: center;
  justify-content: center;
  i {
    font-size: 25px;
  }
}

.step-item--active {
  // color: #2563eb;
  .step-item-label {
    color: #2563eb;
  }
}

.step-item-number {
  width: 36px;
  height: 36px;

  background-color: #f5f7fa;
  color: rgba($color: #000000, $alpha: 0.3);

  border-radius: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 12px;
  font-size: 18px;
}

.step-item--loading {
  .step-item-number {
    background-color: #3366ff;
    color: #fff;
  }
}

.step-item--success {
  .step-item-number {
    background-color: #22c55e;
    color: #fff;
    font-weight: bold;
  }
}

.step-item-label {
  font-size: 16px;
  font-weight: bold;
  color: #000;
}

.step-item-status {
  font-size: 12px;
  margin-top: 6px;
  margin-bottom: 6px;
  color: #999;
}

.page {
  display: flex;
  height: 100%;
  .page-left {
    width: 270px;
    display: flex;
    flex-direction: column;
    margin-right: 16px;
    .title {
      font-size: 16px;
      color: #000;
      font-weight: bold;
      margin-top: 12px;
      margin-bottom: 12px;
    }
  }
  .page-right {
    flex: 1;
    overflow: hidden;
  }
}

.content {
  display: flex;
  gap: 16px;
  height: 100%;
}

.topo {
  flex: 1;
  margin-bottom: 0;
}

.sidebar {
  display: flex;
  flex-direction: column;
  width: 430px;
  // .section {
  //   flex: 1;
  // }
}

@keyframes centerPulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.5; /* 不完全透明，让闪烁更柔和 */
  }
}

.detail {
  display: flex;
  flex-direction: column;
  gap: 24px;
  margin-bottom: 24px;

  .alert-type {
  }

  .level-warp {
    display: flex;
    align-items: center;
  }
}

.level {
  width: 46px;
  line-height: 22px;
  text-align: center;
  border-radius: 23px;
  font-size: 12px;
  font-weight: 600;
}

.level--low {
  border: 1px solid #c0dbfe;
  color: #2563eb;
}

.level--middle {
  background-color: #f59e0b;
  color: #fff;
}

.level--high {
  background-color: #ef4444;
  color: #fff;
}

.info {
  border-bottom: 1px solid #f0f0f0;
}

.info-item {
  display: flex;
  margin-bottom: 12px;
}

.info-item--label {
  color: #999;
}

.info-item--value {
  overflow: hidden;
  flex: 1;
}

.loading {
  width: 100%;
  height: 100%;
  :deep(.section-body) {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
  }
}

.attack {
  background-color: rgba($color: #f56c6c, $alpha: 0.1);
  box-sizing: none;
  border: none;
  color: #f56c6c;
  :deep(.section-title) {
    color: #f56c6c;
  }
}
</style>
